﻿using UnityEngine;
using System.Collections;


[System.Serializable]
public class SfxData
{
	/// <summary>
	/// 재생 방식
	/// </summary>
	public enum Type
	{
		Static,							// 한가운데 고정
		AtPosition,						// 특정 위치에서 고정
		Attached,						// 특정 게임 오브젝트에 부착됨
	}

	public Type		type;

	public string	clipPath;			// 파일 경로
	public bool		looping;			// 루프

	public float	volume;				// 볼륨
	public float	pitchRandomRange;	// 피치 랜덤 범위
}

[System.Serializable]
public class BgmData
{
	public string	clipPath;			// 파일 경로
	public bool		looping;			// 루프
}

[RequireComponent(typeof(AudioSource))]
public class SoundManager : MonoBehaviour
{
	// Constants

	const float			c_maxDistance	= 60f;


	// Members

	static SoundManager	s_instance	= null;
	static SoundManager instance
	{
		get
		{
			return s_instance;
		}
	}


	AudioSource		m_bgmSource;			// BGM 재생용 오디오 소스


	void Awake()
	{
		s_instance	= this;
		m_bgmSource	= GetComponent<AudioSource>();
	}

	/// <summary>
	/// 사운드 이펙트 재생
	/// </summary>
	/// <param name="data"></param>
	public static void PlaySfx(SfxData data, Transform parentObjT = null)
	{
		GameObject clipObj	= new GameObject("Sfx");					// 오브젝트를 만든다
		AudioSource source	= clipObj.AddComponent<AudioSource>();
		source.clip			= ResourceDepot.Load<AudioClip>(Constants.Path.sfx + data.clipPath);
		source.loop			= data.looping;
		source.pitch		= 1 + Random.Range(-data.pitchRandomRange, data.pitchRandomRange);

		//source.maxDistance	= 100000;
		source.rolloffMode	= AudioRolloffMode.Linear;

		if (!data.looping)												// * 루프가 아닐시에는 플레이 후 자동 파괴되게
		{
			instance.StartCoroutine(DestroyWhenPlayingIsDone(source));
		}

		Transform clipT		= clipObj.transform;
		switch (data.type)
		{
			case SfxData.Type.Static:
				clipT.parent		= instance.transform;
				clipT.localPosition	= Vector3.zero;
				break;

			case SfxData.Type.AtPosition:
				//source.maxDistance	= c_maxDistance;
				clipT.parent		= instance.transform;
				clipT.position		= parentObjT.position;
				break;

			case SfxData.Type.Attached:
				//source.maxDistance	= c_maxDistance;
				clipT.parent		= parentObjT;
				clipT.localPosition	= Vector3.zero;
				break;
		}

		source.Play();
	}

	/// <summary>
	/// BGM 재생
	/// </summary>
	/// <param name="data"></param>
	public static void PlayBgm(BgmData data)
	{
		AudioSource bgmSource	= instance.m_bgmSource;

		bgmSource.Stop();
		bgmSource.clip			= ResourceDepot.Load<AudioClip>(Constants.Path.bgm + data.clipPath);
		bgmSource.loop			= data.looping;
		bgmSource.Play();

	}

	public static void StopBgm()
	{
		AudioSource bgmSource	= instance.m_bgmSource;
		bgmSource.Stop();
	}

	static IEnumerator DestroyWhenPlayingIsDone(AudioSource source)
	{
		do
		{
			bool playerNull			= GameScene.playerCharacter == null;
			float dist				= Vector3.Distance(Camera.main.transform.position, source.transform.position);
			//Debug.Log (playerNull);
			source.volume			= (playerNull || dist <= c_maxDistance)? 1f : 0f;
			yield return null;
		}
		while (source != null && source.isPlaying);

		if (source != null && source.gameObject != null)
		{
			Destroy(source.gameObject);
		}
	}
}
